package com.sz.common.base.dao.ext.impl;

import com.sz.common.base.dao.Dao;
import com.sz.common.base.dao.ext.DaoExt;
import com.sz.common.base.dao.ext.EntityDao;
import com.sz.common.base.dao.ext.EntityVersionDao;
import com.sz.common.base.dao.schema.TableSchema;
import com.sz.common.base.entity.VersionEntity;
import com.sz.common.base.utils.DateUtils;
import com.sz.common.base.utils.EntityUtils;
import com.sz.common.base.utils.UUIDGenerator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.sql.Timestamp;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * Package: com.sz.common.base.dao.ext.impl <br>
 * Function: TODO: ADD FUNCTION <br>
 * Author: Charles. <br>
 * Date: 2017-02-21 14:13:00.
 */
@Service
public class EntityVersionDaoSupport implements EntityVersionDao {

    @Autowired
    protected Dao dao;
    @Autowired
    protected DaoExt daoEx;
    @Autowired
    protected EntityDao entityDao;

    /**
     * @param tableSchema
     * @param entity
     */
    @Override
    public void insertEntity(TableSchema tableSchema, VersionEntity entity) {
        if (tableSchema == null || entity == null) {
            throw new IllegalArgumentException("schema and entity cannot be empty");
        }
        if (!StringUtils.hasLength(entity.getUid())) {
            entity.setUid(UUIDGenerator.generateOrderedUUID());
        }
        entity.setIsActive(true);
        if (entity.getActiveTime() == null) {
            Date date = dao.getDbDate();
            entity.setActiveTime(date);
        }
        if (entity.getInactiveTime() == null) {
            entity.setInactiveTime(DateUtils.getFinalDate());
        }
        this.entityDao.insertEntity(tableSchema, entity);
    }

    /**
     * @param tableSchema
     * @param entity
     */
    @Override
    public void updateEntity(TableSchema tableSchema, VersionEntity entity) {
        if (tableSchema == null || entity == null) {
            throw new IllegalArgumentException("table schema and entity cannot be empty");
        }
        Timestamp time = this.dao.getDbDate();
        String uid = entity.getUid();
        this.deleteByUid(tableSchema, uid, time);

        //删除原来的主键值
        String primaryKey = tableSchema.getPrimaryKeyName();
        EntityUtils.setPropertyValue(entity, primaryKey, null);
        //插入新的记录
        this.entityDao.insertEntity(tableSchema, entity);
    }


    /**
     * @param uid
     */
    @Override
    public void deleteByUid(TableSchema tableSchema, String uid) {
        deleteByUid(tableSchema, uid, null, null);
    }

    /**
     * @param uid
     * @param date
     */
    @Override
    public void deleteByUid(TableSchema tableSchema, String uid, Date date) {
        deleteByUid(tableSchema, uid, date, null);
    }

    /**
     * @param uid
     * @param date
     * @param bizFields
     */
    @Override
    public void deleteByUid(TableSchema tableSchema, String uid, Date date, Map<String, Object> bizFields) {
        if (uid == null || uid.trim().length() == 0) {
            throw new IllegalArgumentException("uid cannot be empty");
        }

        Map<String, Object> map = new HashMap<>();
        map.put("tableName", tableSchema.getTableName());
        map.put("uid", uid);
        if (date != null) {
            map.put("inactiveTime", date);
        }

        if (bizFields != null && bizFields.size() > 0) {
            Map<String, Object> fields = new HashMap<>();
            for (Map.Entry<String,Object> entry : bizFields.entrySet()) {
                if (checkField(entry.getKey())) {
                    fields.put(entry.getKey(), entry.getValue());
                }
            }
            map.put("bizFields", fields);
        }
        this.dao.update("VersioningMapper.softDeleteByUID", map);
    }

    private boolean checkField(String fieldName) {
        if (fieldName == null || fieldName.trim().length() == 0) {
            return false;
        }
        return !("tableName".equalsIgnoreCase(fieldName)
                || "uid".equalsIgnoreCase(fieldName)
                || "inactiveTime".equalsIgnoreCase(fieldName));
    }


}
